package processorIO;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import processor.MyException;
import processor.images.ImageProcessor;

/**
 * A class containing methods for loading and saving images.
 * Loading methods loadAsPixelImage image files from hard drive into an internal
 * representation (see below for full list), which can be used by other
 * programs. Saving methods take in a supported internal representation of
 * images and save to the hard drive.
 * 
 * Supported Internal Representation of Images:
 * > java.awt.image.BufferedImage (Java API)
 * > image.PixelImage (custom designed)
 *
 * Fully tested: No
 * Fully documented: Yes
 * Created: November 7, 2011
 * Last updated: July 30, 2012
 * 
 * @author Shimu Wu
 */
public class ImageIO extends FileIO {

    protected ImageIO() {
    }

    /**
     * Returns a BufferedImage that represents the image file at the given
     * file_path. Returns null if the image failed to loadAsPixelImage. 
     * Uses ImageIO.read(File).
     * 
     * @param file_path the path of the image
     * @return a BufferedImage that represents the image file at the given
     * file_path
     * @throws MyException  
     */
    public static BufferedImage loadAsBufferedImage(String file_path)
            throws MyException {
        try {
            BufferedImage img = javax.imageio.ImageIO.read(new File(file_path));
            return img;
        } catch (IOException e) {
            //e.printStackTrace();
            throw new MyException("Picture failed to load: "
                    + file_path, e);
        }
    }

    /**
     * 
     * @param directoryPath the name of directory where all the images are 
     * located (add a "/" to the end of the path)
     * @param fileExtension the file extension of the image files
     * @param totalFrames the total number of image files in the directory
     * @param width the bounding width of the image to be returned in the Image
     * array
     * @param height the bounding height of the image to be returned in the 
     * Image array
     * @return 
     */
    public Image[] loadFrames(String directoryPath, String fileExtension,
            int totalFrames, int width, int height) throws MyException {
        Image[] frames = new Image[totalFrames];
        String name;
        for (int i = 0; i < totalFrames; i++) {
            name = directoryPath + (i + 1) + "." + fileExtension;

            try {
                frames[i] = ImageProcessor.scaleToFit(
                        loadAsBufferedImage(name), width, height,
                        Image.SCALE_SMOOTH);

            } catch (MyException ex) {
                throw new MyException("Cannot load the file " + name, ex);
                //System.err.println("Cannot load the file: " + name);
                //System.exit(0);
            }
        }
        return frames;
    }

    private BufferedImage createBlankImage(BufferedImage img) {
        return new BufferedImage(img.getWidth(), img.getHeight(),
                img.getType());
    }

    /*
    public void modifyImages(String directoryPath, AffineTransform transform)
            throws MyException {
        File directory = new File(directoryPath);
        String[] fileNames = directory.list();
        BufferedImage newImg, originalImg;
        Graphics2D g;
        String fileName;
        for (String name : fileNames) {
            fileName = directoryPath + "/" + name;
            System.out.println("Processing " + fileName);
            originalImg = loadAsBufferedImage(fileName);
            newImg = createBlankImage(originalImg);
            g = newImg.createGraphics();
            g.drawImage(originalImg, transform, null);
            this.saveImage(newImg, fileName);
        }
    }

    public void modifyImages(String directoryPath,
            UnaryFunction<BufferedImage, BufferedImage> transform)
            throws MyException {
        File directory = new File(directoryPath);
        String[] fileNames = directory.list();
        BufferedImage newImg, originalImg;
        Graphics2D g;
        String fileName;
        for (String name : fileNames) {
            fileName = directoryPath + "/" + name;
            System.out.println("Processing " + fileName);
            originalImg = loadAsBufferedImage(fileName);
            newImg = transform.evaluate(originalImg);
            this.saveImage(newImg, fileName);
        }
    }*/

        
}
